package com.echo.im.domain.message.service;


import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.echo.im.common.enums.MessageStatus;
import com.echo.im.common.vo.PrivateMessageVO;

import com.echo.im.infrastructure.generator.IdGenerator;
import com.echo.im.domain.friend.manager.FriendManager;
import com.echo.im.domain.message.dto.PullPrivateOfflineMessageDto;
import com.echo.im.infrastructure.session.SessionContext;
import com.echo.im.infrastructure.session.UserSession;
import com.echo.im.repository.dao.entity.PrivateMessage;
import com.echo.im.repository.dao.mapper.PrivateMessageMapper;
import com.echo.im.repository.offline.OfflineMessageService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 私聊消息服务实现
 * @author echo
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class PrivateMessageServiceImpl extends ServiceImpl<PrivateMessageMapper, PrivateMessage> implements PrivateMessageService {

    private final FriendManager friendManager;
    private final OfflineMessageService<PrivateMessage> privateMessageOfflineMessageService;
    private final IdGenerator idGenerator;

    /**
     *
     * 1.消息是否存在直接丢到客户端判断，我们这里不用判断
     * 2.是否有权撤回消息，例如撤回消息的发送者和被撤回消息的发送者是否相同
     * 3.消息超过时间也由双方客户端判断，如果消息超过xxx分钟，不支持撤回
     * 4.如何知道撤回是否成功呢？如果撤回成功，对端将会回一条撤回成功消息
     * 5.privateStoreMessageListener 要判断撤回消息是否超时，如果超时，就不管他了
     *
     * @param dto
     */


    /**
     * 拉取离线消息,uuid可以是前端生成，也可以是后端通过ip等这些来设置，后期可以更改
     */
    @Override
    public List<PrivateMessageVO> pullOfflineMessage(PullPrivateOfflineMessageDto dto) {
        UserSession session = SessionContext.getSession();
        List<PrivateMessage> offLineMessages =
                privateMessageOfflineMessageService.fetchAndDeleteOfflineMessages(session.getUserId(), dto.getLastMsgId(), dto.getSize(), dto.getSessionUuid());
        List<PrivateMessageVO> privateMessageVOList = BeanUtil.copyToList(offLineMessages, PrivateMessageVO.class);
        return privateMessageVOList;
    }

    /**
     * 直接查询数据库，不支持分页，不能用分页，只能用，上一次查询的Id，然后做limit ？，增量查询
     * @param friendId
     * @param lastMsgId
     * @param size
     * @return
     */
    @Override
    public List<PrivateMessageVO> findHistoryMessage(Long friendId, Long lastMsgId,Integer size) {

        Long userId = SessionContext.getSession().getUserId();

        QueryWrapper<PrivateMessage> wrapper = new QueryWrapper<>();
        wrapper.lambda().and(wrap -> wrap.and(
                                wp -> wp.eq(PrivateMessage::getSendId, userId)
                                        .eq(PrivateMessage::getRecvId, friendId))
                        .or(wp -> wp.eq(PrivateMessage::getRecvId, userId)
                                .eq(PrivateMessage::getSendId, friendId)))
                .ne(PrivateMessage::getStatus, MessageStatus.RECALL.code())
                .gt(PrivateMessage::getId, lastMsgId)
                .orderByDesc(PrivateMessage::getId)
                .last("limit " + size);

        List<PrivateMessage> messages = baseMapper.selectList(wrapper);

        List<PrivateMessageVO> messageInfos = messages.stream().map(m -> BeanUtil.copyProperties(m, PrivateMessageVO.class)).collect(Collectors.toList());
        log.info("拉取聊天记录，用户id:{},好友id:{}，数量:{}", userId, friendId, messageInfos.size());

        return messageInfos;
    }


}
